home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 1 / BBS in a box - Trilogy I.iso / Files / Publish / Photoshop / Plug-in Modules / Code / DummyScan.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-28  |  11.4 KB  |  618 lines  |  [TEXT/MPS ]

  1. /*
  2.     File: DummyScan.c
  3.  
  4.     Copyright 1990 by Thomas Knoll.
  5.     Copyright 1993 by Adobe Systems, Inc.
  6.  
  7.     C source file for DummyScan example.
  8. */
  9.  
  10. #include <Types.h>
  11. #include <Memory.h>
  12. #include <Resources.h>
  13. #include <QuickDraw.h>
  14. #include <Dialogs.h>
  15. #include <OSUtils.h>
  16. #include <Packages.h>
  17. #include <Errors.h>
  18. #include <ToolUtils.h>
  19.  
  20. #include "PITypes.h"
  21. #include "PIGeneral.h"
  22. #include "PIAcquire.h"
  23.  
  24. #include "DialogUtilities.h"
  25. #include "PIUtilities.h"
  26.  
  27. #ifdef THINK_C
  28.  
  29. #define ENTRYPOINT main
  30.  
  31. #endif
  32.  
  33. /*****************************************************************************/
  34.  
  35. typedef struct Globals
  36.     {
  37.  
  38.     short result;
  39.     AcquireRecord *stuff;
  40.     
  41.     short lastImages;
  42.     short lastRows;
  43.     short lastCols;
  44.     short lastMode;
  45.     
  46.     short nextImage;
  47.     short nextRow;
  48.     short nextPlane;
  49.     short chunkRows;
  50.     long  rowBytes;
  51.     
  52.     long done;
  53.     long total;
  54.     
  55.     BufferID buffer;
  56.     
  57.     Boolean postProcessing;
  58.     
  59.     } Globals, *GPtr, **GHdl;
  60.     
  61. #define gResult ((**globals).result)
  62. #define gStuff  ((**globals).stuff)
  63.  
  64. #define gLastImages ((**globals).lastImages)
  65. #define gLastRows ((**globals).lastRows)
  66. #define gLastCols ((**globals).lastCols)
  67. #define gLastMode ((**globals).lastMode)
  68.  
  69. #define gNextImage ((**globals).nextImage)
  70. #define gNextRow ((**globals).nextRow)
  71. #define gNextPlane ((**globals).nextPlane)
  72. #define gChunkRows ((**globals).chunkRows)
  73. #define gRowBytes ((**globals).rowBytes)
  74.  
  75. #define gDone ((**globals).done)
  76. #define gTotal ((**globals).total)
  77.  
  78. #define gBuffer ((**globals).buffer)
  79.  
  80. #define gPostProcessing ((**globals).postProcessing)
  81.  
  82. /*****************************************************************************/
  83.  
  84. void InitGlobals (GHdl globals);
  85.  
  86. void DoAbout (GHdl globals);
  87. void DoPrepare (GHdl globals);
  88. void DoStart (GHdl globals);
  89. void DoContinue (GHdl globals);
  90. void DoFinish (GHdl globals);
  91.  
  92. /*****************************************************************************/
  93.  
  94. /* All calls to the plug-in module come through this routine. It must be
  95.    placed first in the resource. To achieve this, most development systems
  96.    require that this be the first routine in the source. */
  97.  
  98. pascal void ENTRYPOINT (short selector,
  99.                         AcquireRecord *stuff,
  100.                         long *data,
  101.                         short *result)
  102.     {
  103.     
  104.     GHdl globals;
  105.     
  106.     if (!*data)
  107.         {
  108.  
  109.         *data = (long) NewHandle (sizeof (Globals));
  110.         
  111.         if (!*data)
  112.             {
  113.             *result = memFullErr;
  114.             return;
  115.             }
  116.             
  117.         InitGlobals ((GHdl) *data);
  118.         
  119.         }
  120.         
  121.     globals = (GHdl) *data;
  122.         
  123.     gStuff = stuff;
  124.     gResult = noErr;
  125.         
  126.     switch (selector)
  127.         {
  128.         
  129.         case acquireSelectorAbout:
  130.             DoAbout (globals);
  131.             break;
  132.             
  133.         case acquireSelectorPrepare:
  134.             DoPrepare (globals);
  135.             break;
  136.         
  137.         case acquireSelectorStart:
  138.             DoStart (globals);
  139.             break;
  140.         
  141.         case acquireSelectorContinue:
  142.             DoContinue (globals);
  143.             break;
  144.         
  145.         case acquireSelectorFinish:
  146.             DoFinish (globals);
  147.             break;
  148.             
  149.         default:
  150.             gResult = acquireBadParameters;
  151.         
  152.         }
  153.         
  154.     *result = gResult;
  155.         
  156.     }
  157.  
  158. /*****************************************************************************/
  159.  
  160. void InitGlobals (GHdl globals)
  161.     {
  162.     
  163.     gLastImages = 1;
  164.     gLastRows = 256;
  165.     gLastCols = 256;
  166.     gLastMode = plugInModeRGBColor;
  167.     
  168.     gBuffer = 0;
  169.     
  170.     }
  171.  
  172. /*****************************************************************************/
  173.  
  174. /* Displays the about dialog box for the plug-in module. */
  175.  
  176. void DoAbout (GHdl globals)
  177.     {
  178.  
  179.     #pragma unused (globals)
  180.     
  181.     #define dialogID 16000
  182.     
  183.     ShowAbout (dialogID);
  184.  
  185.     #undef dialogID
  186.  
  187.     }
  188.  
  189. /*****************************************************************************/
  190.  
  191. /* Prepare to acquire an image.    If the plug-in module needs a large amount
  192.    of buffer memory, this routine should set the maxData field to the
  193.    number of bytes required.  Since we are going to use the bufferProcs,
  194.    we simply set maxData to zero.  */
  195.  
  196. void DoPrepare (GHdl globals)
  197.     {
  198.     
  199.     gStuff->maxData = 0;
  200.     
  201.     if (!WarnBufferProcsAvailable ())
  202.         gResult = 1;
  203.         
  204.     /* Prepare is called before we bring up the dialog but not on subsequent
  205.        acquires so this is a good place to detect the beginning of an
  206.        acquisition sequence. */
  207.         
  208.     gNextImage = 0;
  209.     
  210.     }
  211.  
  212. /*****************************************************************************/
  213.  
  214. Boolean GetParameters (GHdl globals);
  215.  
  216. /*****************************************************************************/
  217.  
  218. void DoStart (GHdl globals)
  219.     {
  220.     
  221.     short j;
  222.     
  223.     /* Insist on having the buffer procs.
  224.     
  225.     if (!WarnBufferProcsAvailable ())
  226.         {
  227.         gResult = 1;
  228.         return;
  229.         }
  230.         
  231.     /* If this is the first image in a sequence, then we need to query the
  232.        user for the parameters.  We could also write this so that it queries
  233.        on each iteration. */
  234.         
  235.     if (gNextImage == 0)
  236.         {
  237.         
  238.         if (GetParameters (globals))
  239.             ++gNextImage;    /* Advance to the first image. */
  240.  
  241.         else
  242.             {
  243.             gResult = 1;
  244.             return;
  245.             }
  246.  
  247.         }
  248.         
  249.     /* Fill in the parameters for the document. */
  250.     
  251.     gStuff->imageSize.v = gLastRows;
  252.     gStuff->imageSize.h = gLastCols;
  253.     gStuff->imageMode    = gLastMode;
  254.  
  255.     if (gStuff->imageMode == plugInModeBitmap)
  256.         gStuff->depth = 1;
  257.     else
  258.         gStuff->depth = 8;
  259.  
  260.     if (gStuff->imageMode == plugInModeRGBColor)
  261.         gStuff->planes = 3;
  262.     else
  263.         gStuff->planes = 1;
  264.  
  265.     if (gStuff->depth == 1)
  266.         {
  267.         gStuff->imageHRes = FixRatio (300, 1);
  268.         gStuff->imageVRes = FixRatio (300, 1);
  269.         }
  270.     else
  271.         {
  272.         gStuff->imageHRes = FixRatio (72, 1);
  273.         gStuff->imageVRes = FixRatio (72, 1);
  274.         }
  275.  
  276.     if (gStuff->imageMode == plugInModeIndexedColor)
  277.         for (j = 0; j < 256; j++)
  278.             {
  279.             gStuff->redLUT     [j] = j;
  280.             gStuff->greenLUT [j] = 255 - j;
  281.             gStuff->blueLUT  [j] = j;
  282.             }
  283.         
  284.     gStuff->data = nil;
  285.     gBuffer = 0;
  286.     
  287.     gDone = 0;
  288.     gTotal = (long) gStuff->imageSize.v * (long) gStuff->planes;
  289.     
  290.     /* Scale total for post-processing. */
  291.     
  292.     if (gStuff->imageMode != plugInModeBitmap && gStuff->canReadBack)
  293.         gTotal *= 3;
  294.     
  295.     }
  296.  
  297. /*****************************************************************************/
  298.  
  299. void DoContinue (GHdl globals)
  300.     {
  301.     
  302.     long bottom;
  303.     
  304.     /* Allocate the buffer and start acquisition. */
  305.         
  306.     if (!gBuffer)
  307.         {
  308.         
  309.         int16 actualHeight;
  310.         BufferID buffer;
  311.         
  312.         if (gStuff->depth == 8)
  313.             gRowBytes = gStuff->imageSize.h;
  314.         else
  315.             gRowBytes = (gStuff->imageSize.h + 7) >> 3;
  316.             
  317.         gResult = AllocateStripBuffer (gRowBytes,
  318.                                        1,
  319.                                        gStuff->imageSize.v,
  320.                                        1,
  321.                                        &actualHeight,
  322.                                        &buffer);
  323.         
  324.         gChunkRows = actualHeight;                               
  325.         gBuffer = buffer;
  326.         
  327.         if (gResult != noErr)
  328.             return;
  329.             
  330.         gStuff->data = LockBuffer (gBuffer, FALSE);
  331.         
  332.         gPostProcessing = FALSE;
  333.         
  334.         gStuff->wantReadBack = FALSE;
  335.         
  336.         gNextPlane = 0;
  337.         gNextRow = 0;
  338.         
  339.         }
  340.         
  341.     /* Determine whether to advance to the next plane. */
  342.     
  343.     if (gNextRow >= gStuff->imageSize.v)
  344.         {
  345.         ++gNextPlane;
  346.         gNextRow = 0;
  347.         }
  348.         
  349.     /* Determine whether to advance to the next stage. */
  350.     
  351.     if (gNextPlane >= gStuff->planes)
  352.         {
  353.         
  354.         if (gPostProcessing ||
  355.             gStuff->imageMode == plugInModeBitmap ||
  356.             !gStuff->canReadBack)
  357.             {
  358.             
  359.             gStuff->data = nil;
  360.             SetRect (&gStuff->theRect, 0, 0, 0, 0);
  361.             
  362.             return;
  363.             
  364.             }
  365.             
  366.         else
  367.             {
  368.             
  369.             gPostProcessing = TRUE;
  370.             
  371.             gNextPlane = 0;
  372.             gNextRow = 0;
  373.             
  374.             }
  375.         
  376.         }
  377.     
  378.     /* Set up the rectangle to process. */
  379.     
  380.     gStuff->loPlane = gNextPlane;
  381.     gStuff->hiPlane = gNextPlane;
  382.     
  383.     bottom = gNextRow + (long) gChunkRows;
  384.     if (bottom > gStuff->imageSize.v)
  385.         bottom = gStuff->imageSize.v;
  386.     
  387.     gStuff->theRect.top = gNextRow;
  388.     gStuff->theRect.bottom = bottom;
  389.     gStuff->theRect.left = 0;
  390.     gStuff->theRect.right = gStuff->imageSize.v;
  391.     
  392.     gStuff->rowBytes = gRowBytes;
  393.     gStuff->colBytes = 1;
  394.     
  395.     /* If we are not post-processing, then store the data. */
  396.     
  397.     if (!gPostProcessing)
  398.         {
  399.         
  400.         int16 row;
  401.         Ptr p;
  402.         
  403.         for (row = gStuff->theRect.top, p = gStuff->data;
  404.              row < gStuff->theRect.bottom;
  405.              ++row, p += gRowBytes)
  406.             {
  407.             
  408.             int16 col; 
  409.             Ptr q;
  410.  
  411.             if (TestAbort ())
  412.                 {
  413.                 gResult = 1;
  414.                 return;
  415.                 }
  416.                 
  417.             UpdateProgress (gDone++, gTotal);
  418.             
  419.             for (col = 0, q = p;
  420.                  col < gRowBytes;
  421.                  ++col, ++q)
  422.                 {
  423.                 
  424.                 if (gStuff->depth == 1)
  425.                     *q = 0xFF << (row & 7);
  426.                 else if (gStuff->planes == 1)
  427.                     *q = row + col;
  428.                 else if (gNextPlane == 0)
  429.                     *q = col;
  430.                 else if (gNextPlane == 1)
  431.                     *q = row;
  432.                 else
  433.                     *q = row + col;
  434.                 
  435.                 }
  436.             
  437.             }
  438.         
  439.         gNextRow = gStuff->theRect.bottom;
  440.         
  441.         }
  442.     
  443.     /* Else if the last operation was not a read, then read. */
  444.        
  445.     else if (!gStuff->wantReadBack)
  446.         {
  447.         
  448.         /* We know that we can read back because we only set gPostProcessing
  449.            true if gStuff->canReadBack is true. */
  450.         
  451.         gStuff->wantReadBack = TRUE;
  452.         
  453.         gDone += gStuff->theRect.bottom - gStuff->theRect.top;
  454.         
  455.         }
  456.         
  457.     /* Otherwise, do the post-processing. */
  458.  
  459.     else
  460.         {
  461.         
  462.         int16 row;
  463.         Ptr p;
  464.         
  465.         for (row = gStuff->theRect.top, p = gStuff->data;
  466.              row < gStuff->theRect.bottom;
  467.              ++row, p += gRowBytes)
  468.             {
  469.             
  470.             int16 col; 
  471.             Ptr q;
  472.  
  473.             if (TestAbort ())
  474.                 {
  475.                 gResult = 1;
  476.                 return;
  477.                 }
  478.                 
  479.             UpdateProgress (gDone++, gTotal);
  480.             
  481.             for (col = gStuff->theRect.left, q = p;
  482.                  col < gStuff->theRect.right;
  483.                  ++col, ++q)
  484.                 {
  485.                 
  486.                 short value = *q & 0x00FF;
  487.                 
  488.                 value /= gNextImage;
  489.                 
  490.                 *q = value;
  491.                 
  492.                 }
  493.             
  494.             }
  495.         
  496.         gStuff->wantReadBack = FALSE;
  497.         
  498.         gNextRow = gStuff->theRect.bottom;
  499.         
  500.         }
  501.         
  502.     }
  503.  
  504. /*****************************************************************************/
  505.  
  506. /* This routine will always be called if DoStart does not return an error
  507.    (even if DoContinue returns an error or the user aborts the operation).
  508.    This allows the module to perform any needed cleanup. */
  509.  
  510. void DoFinish (GHdl globals)
  511.     {
  512.     
  513.     if (gBuffer)
  514.         FreeBuffer (gBuffer);
  515.         
  516.     gBuffer = 0;
  517.     
  518.     ++gNextImage;
  519.     
  520.     gStuff->acquireAgain = gNextImage <= gLastImages;
  521.     
  522.     }
  523.  
  524. /*****************************************************************************/
  525.  
  526. /* Prompt the user for the image parameters.
  527.    Returns false if the user cancels. */
  528.  
  529. Boolean GetParameters (GHdl globals)
  530.     {
  531.     
  532.     #define dialogID        16001
  533.     #define hookItem        3
  534.     #define imagesItem        4
  535.     #define rowsItem        5
  536.     #define colsItem        6
  537.     #define firstModeItem    7
  538.     #define lastModeItem    10
  539.     
  540.     DialogPtr dp;
  541.     DialogTHndl dt;
  542.  
  543.     short item;
  544.     
  545.     long xImages = gLastImages;
  546.     long xRows = gLastRows;
  547.     long xCols = gLastCols;
  548.     short modeItem = gLastMode - plugInModeBitmap + firstModeItem;
  549.     
  550.     dt = (DialogTHndl) GetResource ('DLOG', dialogID);
  551.     HNoPurge ((Handle) dt);
  552.  
  553.     CenterDialog (dt);
  554.     SetUpMoveableModal (dt, gStuff->hostSig);
  555.     
  556.     dp = GetNewDialog (dialogID, nil, (WindowPtr) -1);
  557.     
  558.     SetOutlineOKHook (dp, hookItem);
  559.     
  560.     StuffNumber (dp, imagesItem, xImages);
  561.     StuffNumber (dp, rowsItem, xRows);
  562.     StuffNumber (dp, colsItem, xCols);
  563.     SetRadioGroupState (dp, firstModeItem, lastModeItem, modeItem);
  564.     
  565.     SelectTextItem (dp, imagesItem);
  566.     
  567.     do
  568.         {
  569.         
  570.         MoveableModalDialog (dp, gStuff->processEvent, nil, &item);
  571.  
  572.         if (item >= firstModeItem && item <= lastModeItem)
  573.             SetRadioGroupState (dp, firstModeItem, lastModeItem, item);
  574.  
  575.         else if (item == ok)
  576.             {
  577.             
  578.             modeItem = GetRadioGroupState (dp, firstModeItem, lastModeItem);
  579.             
  580.             if (modeItem == 0 ||
  581.                 !FetchNumber (dp, imagesItem, 1, 10,  &xImages) ||
  582.                 !FetchNumber (dp, rowsItem, 1, 30000, &xRows) ||
  583.                 !FetchNumber (dp, colsItem, 1, 30000, &xCols))
  584.                 {
  585.                 
  586.                 item = 0;
  587.                 
  588.                 }
  589.                 
  590.             }
  591.  
  592.         }
  593.     while (item != ok && item != cancel);
  594.  
  595.     DisposDialog (dp);
  596.     HPurge ((Handle) dt);
  597.  
  598.     if (item == ok)
  599.         {
  600.         gLastImages = (short) xImages;
  601.         gLastRows = (short) xRows;
  602.         gLastCols = (short) xCols;
  603.         gLastMode = modeItem - firstModeItem + plugInModeBitmap;
  604.         }
  605.  
  606.     return item == ok;
  607.  
  608.     #undef dialogID
  609.     #undef hookItem
  610.     #undef rowsItem
  611.     #undef colsItem
  612.     #undef firstModeItem
  613.     #undef lastModeItem
  614.     
  615.     }
  616.  
  617. /*****************************************************************************/
  618.